﻿using System;
using System.Configuration;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Sustainalytics.AwsS3.Client;

namespace BulkUploadGovernanceFiles.MoveInsightToS3Buckets
{

    public interface IFileUpload
    {
        //Task UploadAsynk(string fileName, byte[] file);
        Task UploadAsynk(string fileName, Stream fileStream);
        Task UploadAsynk(string fileName, Stream content, Guid id, string contentType = null);
        Task Delete(string fileName);
    }
    public class S3BucketFileUpload //: IFileUpload
    {

        private readonly IS3Client _s3Client;
        private readonly string _bucketName;
        private readonly string _s3Folder;

        public S3BucketFileUpload()
        {
            var bucketName = ConfigManager.S3Bucket.BucketName;
            var s3Folder = ConfigManager.S3Bucket.FolderName;
            var s3ClientSetings = new S3ClientSettings()
            {
                AccessKey = ConfigManager.S3Bucket.AccessKeyId,
                SecretAccessKey = ConfigManager.S3Bucket.SecretAccessKey, //ConfigurationManager.AppSettings["awsSecretKey"],
                ServiceEndPoint = ConfigManager.S3Bucket.ServiceEndPoint,// ConfigurationManager.AppSettings["s3ServiceEndPoint"]
            };
            var s3Client = new S3Client(s3ClientSetings);

            _s3Client = s3Client;
            _bucketName = bucketName;
            _s3Folder = s3Folder;
        }

        public S3BucketFileUpload(IS3Client s3Client, string bucketName, string s3Folder)
        {
            _s3Client = s3Client;
            _bucketName = bucketName;
            _s3Folder = s3Folder;
        }

        #region commented method using a diffrent version o AWSS3 client
        /*
        public byte[] Download(string reportName)
        {
            byte[] report = null;

            //try
            //{
                report = _s3Client.DownloadFile(new S3DownloadDetails
                {
                    BucketName = _bucketName,
                    Key = string.Format("{0}/{1}", _s3Folder, reportName)
                });
            //}
            //catch (Exception exception)
            //{
            //    throw new NotFoundException("Report", exception);
            //}

            //if (report.Length == 0)
            //    throw new NotFoundException("Report");

            return report;
        }

        public async Task UploadAsynk(string fileName, byte[] file)
        {
            var request = new S3UploadDetails
            {
                BucketName = _bucketName,
                Key = string.Format("{0}/{1}", _s3Folder, fileName),
                FileBytes = file,
            };
            var response = await _s3Client.UploadFileAsync(request, CancellationToken.None);
            
        }

        public async Task Delete(string fileName)
        {
            var request = new S3DeleteDetails
            {
                BucketName = _bucketName,
                Key = string.Format("{0}/{1}", _s3Folder, fileName),
                //Key = _fileName,
            };
            await _s3Client.DeleteFileAsync(request, CancellationToken.None);
        }
        

        public async Task UploadAsynk(string fileName, Stream fileStream)
        {
            await UploadAsynk(fileName, ReadByteArrayFromStream(fileStream));
        }
        /// <summary>
        /// Upload file to S3 bucket
        /// </summary>
        /// <param name="fileName">Folder name \ file name </param>
        /// <param name="content"></param>
        /// <param name="id"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public async Task UploadAsynk(string fileName, Stream content, Guid id, string contentType = null)
        {
            var fileIdentifier = id.ToString() + fileName;
            await UploadAsynk(fileIdentifier, ReadByteArrayFromStream(content));
            //return id;
        }


        public static byte[] ReadByteArrayFromStream(Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }
        */
        #endregion
    }
}